package recorder 
{
	import collisions.LinkedList;
	import entities.Entity;
	import flash.utils.Dictionary;
	import recorder.RecordData;
	/**
	 * ...
	 * @author Gareth Williams
	 */
	public class EntityStateRecorder implements IRecorder 
	{
		private var recordingHead:LinkedList = new LinkedList(new RecordData(Main.timestep));
		private var recordingTail:LinkedList = recordingHead;
		private var what:Entity;
		
		private const properties:Array = ["isAlive"];
		
		public function EntityStateRecorder(what:Entity) 
		{
			//first record should indicate dead
			recordingTail.object["isAlive"] = false;
			recordingTail.next = new LinkedList(new RecordData(Main.timestep));
			//next record will be overwritten because initial state of entity is always alive
			recordingTail = recordingTail.next;
			
			this.what = what;
		}
	
		/* INTERFACE recorder.IRecorder */
		
		public function update():void 
		{
			var data:RecordData = new RecordData(Main.timestep);
			
			var isRepeatData:Boolean = true;//flag whether to bother adding this record...
			for each (var state:String in properties)
			{
				var previousRecord:RecordData = RecordData(recordingTail.object);
				if (what[state] !== previousRecord[state])
				{
					isRepeatData = false;
				}
				data[state] = what[state];
			}
			
			if (isRepeatData) return;
			
			//insert into list at correct timestep...
			var recordIterator:LinkedList = recordingHead;
			while(recordIterator.next !== null)
			{
				if (RecordData(recordIterator.next.object).timestep > Main.timestep) break;
				recordIterator = recordIterator.next;
			}
			recordingTail = recordIterator;
			
			//overwrite or insert
			if (RecordData(recordIterator.object).timestep === Main.timestep)
			{
				recordingTail.object = data;
			}
			else //insert or add to the end (insert between last item and null next item)
			{
				var insert:LinkedList = new LinkedList(data);
				insert.next = recordingTail.next;
				recordingTail.next = insert;
			}
		}
		public function retrieveDataAt(timestep:Number):RecordData 
		{
			//find nearest record of state to timestep
			var recordIterator:LinkedList = recordingHead;
			while(recordIterator.next !== null)
			{
				if (RecordData(recordIterator.next.object).timestep > timestep) break;
				recordIterator = recordIterator.next;
			}
			
			return RecordData(recordIterator.object); 
		}
		public function getLastTimestep():Number
		{
			return RecordData(recordingTail.object).timestep;
		}
		public function getFirstTimestep():Number
		{
			return RecordData(recordingHead.object).timestep;
		}
		public function rewind():void
		{
			recordingTail = recordingHead;
		}
	}
}